/*
 * PipesCanvas.java
 *
 * Created on 31 juli 2006, 0:50
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package be.drapier;

import java.io.IOException;
import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.game.GameCanvas;
import javax.microedition.lcdui.game.LayerManager;
import javax.microedition.lcdui.game.Sprite;
import javax.microedition.lcdui.game.TiledLayer;

/**
 *
 * @author Wim Drapier
 */
public class PipesCanvas extends GameCanvas implements Runnable {
    
    private LayerManager lm;
    private Sprite playerSprite;
    
    private GameField gf;
    
    /** Thread used for key handling and animation */
    private Thread gamingThread;
    
    /** Creates a new instance of PipesCanvas */
    public PipesCanvas() {
        super(false); // Don't suppress key events
        lm = new LayerManager();
        gf = new GameField(5,5);
        try {
            Image playerImage = Image.createImage("/res/selectedfield.png");
            playerSprite = new Sprite(playerImage, 32, 32);
            lm.append(playerSprite);
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    /**
     * Deprecated, handled automatic by the overriden showNotify() method
     */
    public void start() {
        //gameRunning = true;
    }
    
    /**
     * The main event processor. Events are polled and
     * actions taken based on the directional events.
     */
    public void run() {
        // TODO implement frames per second;
        Graphics g =  getGraphics();
        Thread thread = Thread.currentThread();
        renderGameField(g);
        while(thread == gamingThread) {
            updatePlayerSprite(g);
            g.setColor(255, 255, 255);
            g.fillRect(0, 0,getWidth(), getHeight());
            lm.paint(g,0,0);
            if (thread == gamingThread)
                flushGraphics();
            try {
                thread.sleep(1000 / 60);
            } catch (InterruptedException ex) {
                //ex.printStackTrace();
                stop();
            }
        }
    }
    
    /**
     * Deprecated, handled automatic by the overriden hideNotify() method
     */
    public void stop() {
        //gameRunning = false;
    }
    
    private void renderGameField(Graphics g) {
        TiledLayer tl;
        try {
            Image theme = Image.createImage("/res/theme.png");
            tl = new TiledLayer(gf.getCols(), gf.getRows(), theme, 32, 32);
            tl.fillCells(0, 0, gf.getCols(), gf.getRows(), 1);
            lm.append(tl);
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    private void updatePlayerSprite(Graphics g) {
        int loc = gf.getSelectedField();
        int cell = 32; //number of pixels in a cell
        int x = (loc & 0x7fff) * cell;
        int y = ((loc >> 16) & 0x7fff) * cell;
        playerSprite.setPosition(x,y);
        playerSprite.nextFrame();
    }

     /**
     * Handle a single key event.
     * The LEFT, RIGHT, UP, and DOWN keys are used to
     * move the selected field within the GameField.
     * Other keys are ignored and have no effect.
     * Repaint the screen on every action key(for now this is done by the run method).
     */
    protected void keyPressed(int keyCode) {
        int action = getGameAction(keyCode);
        switch (action) {
            case UP:
                gf.move(GameField.UP);
                break;
            case DOWN:
                gf.move(GameField.DOWN);
                break;
            case LEFT:
                gf.move(GameField.LEFT);
                break;
            case RIGHT:
                gf.move(GameField.RIGHT);
                break;
            default:
                break;
        }
    }

    /**
     * Handle a repeated arrow keys as though it were another press.
     * @param keyCode the key pressed.
     */
    protected void keyRepeated(int keyCode) {
        int action = getGameAction(keyCode);
        switch (action) {
            case LEFT:
            case RIGHT:
            case UP:
            case DOWN:
                keyPressed(keyCode);
	    break;
        default:
            return;
        }
    }

    /**
     * The canvas is being displayed.
     * Stop the event handling and animation thread.
     */
    protected void showNotify() {
        gamingThread = new Thread(this);
        gamingThread.start();
    }

    /**
     * The canvas is being removed from the screen.
     * Stop the event handling and animation thread.
     */
    protected void hideNotify() {
        gamingThread = null;
    }
    
}
